from django.db import models
from DataCenter.code import Code
import datetime
from django.core.cache import cache
from Dashboard.code import AccessCheck
from django.db.models.signals import post_delete, pre_delete, post_save, pre_save
from django.dispatch import receiver

# Create your models here.
class BaseModel(models.Model):
    class Meta:
        abstract = True

    source = models.CharField("数据来源", max_length=255, blank=True, null=True)
    priority = models.IntegerField("优先级", default=10)
    lock = models.BooleanField("锁定", default=False)
    mode = models.CharField('更新模式', max_length=2, choices=Code.UPDATE_MODE_CHOCIE, default='01')
    remarks = models.CharField("备注", max_length=255, blank=True, null=True)
    create_time = models.DateTimeField("创建时间", auto_now_add=True)
    update_time = models.DateTimeField("更新时间", auto_now=True)

    def short_remarks(self):
        if len(str(self.remarks)) > 6:
            return '{0}...'.format(str(self.remarks)[0:6])
        else:
            return self.remarks
    short_remarks.short_description = '备注'


class Contacts(BaseModel):
    class Meta:
        verbose_name = '通讯方式信息'
        verbose_name_plural = '通讯方式信息'
        managed = False
    xgh = models.CharField("学工号", max_length=32, unique=True)
    yzbm = models.CharField("邮政编码", max_length=32, blank=True, null=True)
    txdz = models.CharField("通信地址", max_length=32, blank=True, null=True)
    gddh = models.CharField("固定电话", max_length=32, blank=True, null=True)
    yddh = models.CharField("移动电话", max_length=32, blank=True, null=True)
    dh = models.CharField("短号", max_length=32, blank=True, null=True)
    czdh = models.CharField("传真电话", max_length=32, blank=True, null=True)
    dzxx = models.CharField("电子信箱", max_length=32, blank=True, null=True)
    wldz = models.CharField("网络地址", max_length=32, blank=True, null=True)
    qq = models.CharField("QQ", max_length=32, blank=True, null=True)
    wx = models.CharField("微信", max_length=32, blank=True, null=True)

    def __str__(self):
        return self.xgh;


# 人员数据基本信息
class UserBaseModel(BaseModel):
    class Meta:
        abstract = True
    xgh = models.CharField("学工号", max_length=32, unique=True)
    xm = models.CharField("姓名", max_length=128)
    ywxm = models.CharField("英文姓名", max_length=128, blank=True, null=True)
    xmpy = models.CharField("姓名拼音", max_length=128, blank=True, null=True)
    cym = models.CharField("曾用名", max_length=128, blank=True, null=True)
    xbm = models.CharField("性别", max_length=1, choices=Code.SEX_CHOICE, blank=True, null=True, help_text='不填则自动从身份证获取')
    csrq = models.CharField("出生日期", max_length=32, blank=True, null=True, help_text='不填则自动从身份证获取')
    csdm = models.CharField("出生地", max_length=32, choices=Code.XZQY_CHOICE, blank=True, null=True, help_text='不填则自动从身份证获取')
    jg = models.CharField("籍贯", max_length=32, choices=Code.JG_CHOICE, blank=True, null=True)
    mzm = models.CharField("民族", max_length=32, choices=Code.MZ_CHOICE, blank=True, null=True)
    gjdqm = models.CharField("国籍/地区", max_length=128, blank=True, null=True)
    sfzjlxm = models.CharField("身份证件类型", max_length=1, choices=Code.IDCARD_TYPE_CHOICE, blank=True, null=True)
    sfzjh = models.CharField("身份证件号", max_length=32, blank=True, null=True)
    hyzkm = models.CharField("婚姻状况", max_length=32, choices=Code.HYZKM_CHOICE, blank=True, null=True)
    gatqwm = models.CharField("港澳台侨外", max_length=2, choices=Code.GATQWM_CHOICE, blank=True, null=True)
    zzmmm = models.CharField("政治面貌", max_length=32, choices=Code.POLITICS_STATUS_CHOICE, blank=True, null=True)
    jkzkm = models.CharField("健康状况", max_length=32, choices=Code.JKZKM_CHOICE, blank=True, null=True)
    xyzjm = models.CharField("信仰宗教", max_length=32, blank=True, null=True)
    xxm = models.CharField("血型", max_length=32, choices=Code.BLOOD_TYPE_CHOICE, blank=True, null=True)
    zp = models.CharField("照片", max_length=128, blank=True, null=True)
    sfzjyxq = models.CharField("身份证件有效期", max_length=128, blank=True, null=True)

    def short_name(self):
        if len(str(self.xm)) > 6:
            return '{0}...'.format(str(self.xm)[0:6])
        else:
            return self.xm
    short_name.short_description = '姓名'

    def age(self):
        if self.csrq:
            now_year = datetime.datetime.now().year
            return str(now_year - int(self.csrq[0:4])) + '岁'

    age.short_description = '年龄'


# 教师基本信息
class Gxjg0101(UserBaseModel):
    class Meta:
        verbose_name = '教师基本信息'
        verbose_name_plural = '教师基本信息(即时更新)'

    gkdwh = models.CharField("挂靠单位", max_length=5, choices=Code.DEPARTMENT_CHOICE, blank=True, null=True, help_text='当人事关系不在工作单位时填写')
    dwh = models.CharField("工作单位", max_length=5, choices=Code.DEPARTMENT_CHOICE, blank=True, null=True)
    xqm = models.CharField("校区", max_length=32, choices=Code.CAMPUS_CHOICE, blank=True, null=True)
    zgxlm = models.CharField("最高学历", max_length=32, choices=Code.XL_CHOICE, blank=True, null=True, help_text='博士后是职务，不是学历！')
    whcdm = models.CharField("文化程度", max_length=32, blank=True, null=True)
    cjgzny = models.CharField("参加工作年月", max_length=32, blank=True, null=True)
    lxrq = models.CharField("来校日期", max_length=32, blank=True, null=True)
    qxrq = models.CharField("起薪日期", max_length=32, blank=True, null=True)
    cjny = models.CharField("从教年月", max_length=32, blank=True, null=True)
    bzlbm = models.CharField("编制类别", max_length=32, choices=Code.BZLB_CHOICE, blank=True, null=True)
    jzglbm = models.CharField("教职工类别", max_length=2, choices=Code.JZGLBM_CHOICE, blank=True, null=True)
    dabh = models.CharField("档案编号", max_length=32, blank=True, null=True)
    dawb = models.CharField("档案文本", max_length=32, blank=True, null=True)
    dqztm = models.CharField("当前状态", max_length=32, choices=Code.TEACHER_STATUS_CHOICE, blank=True, null=True, default='1')
    tc = models.CharField("特长", max_length=32, blank=True, null=True)
    xklbm = models.CharField("学科类别", max_length=32, blank=True, null=True)
    yjxkm = models.CharField("一级学科", max_length=32, blank=True, null=True)
    ejxkm = models.CharField("二级学科", max_length=32, blank=True, null=True)
    yjfx = models.CharField("研究方向", max_length=32, blank=True, null=True)
    type = models.IntegerField("身份类型", choices=Code.TEACHER_TYPE_CHOICE, default=1)
    zc = models.CharField("职称", max_length=32, blank=True, null=True)
    zcjb = models.CharField("职称级别", max_length=32, choices=Code.ZCJB_CHOICE, blank=True, null=True)
    zw = models.CharField("职务", max_length=128, blank=True, null=True)
    zj = models.CharField("职级", max_length=32, choices=Code.ZJ_CHOICE, blank=True, null=True)

    def __str__(self):
        return self.xm


# 学生基本信息
class Gxxs0101(UserBaseModel):
    class Meta:
        verbose_name = '学生基本信息'
        verbose_name_plural = '学生基本信息（每5分钟更新）'

    # 基本信息
    yhkh = models.CharField("银行卡号", max_length=32, blank=True, null=True)
    sfdszn = models.CharField("是否独生子女", max_length=32, blank=True, null=True)

    # 学籍信息
    rxny = models.CharField("入学年月", max_length=32, blank=True, null=True)
    xslbm = models.CharField("类别", max_length=32, choices=Code.XSLBM_CHOICE, blank=True, null=True)
    xz = models.CharField("学制", max_length=32, blank=True, null=True)
    szbh = models.CharField("班级", max_length=32, blank=True, null=True)
    sznj = models.CharField("年级", max_length=32, blank=True, null=True)
    yxsh = models.CharField("院系", max_length=32, choices=Code.FACULTY_CHOICE, blank=True, null=True)
    deyxmc = models.CharField("第二院系名称", max_length=32, choices=Code.FACULTY_CHOICE, blank=True, null=True)
    zym = models.CharField("专业", max_length=32, blank=True, null=True)
    xkmlm = models.CharField("学科门类", max_length=32, blank=True, null=True)
    pyfsm = models.CharField("培养方式", max_length=32,choices=Code.PYFSM_CHOICE, blank=True, null=True)
    yjfx = models.CharField("研究方向", max_length=32, blank=True, null=True)
    dsh = models.CharField("导师号", max_length=32, blank=True, null=True)
    hdxlfsm = models.CharField("获得学历方式", max_length=32, blank=True, null=True)
    sfxfz = models.CharField("是否学分制", max_length=32, blank=True, null=True)
    pyccm = models.CharField("培养层次", max_length=32, choices=Code.PYCCM_CHOICE, blank=True, null=True)
    ldfsm = models.CharField("连读方式", max_length=32, blank=True, null=True)
    xsdqztm = models.CharField("状态", max_length=32, choices=Code.XSDQZTM_CHOICE, blank=True, null=True)

    def __str__(self):
        return self.xm


# 职务基本信息
class Duty(BaseModel):
    class Meta:
        verbose_name = '职务信息'
        verbose_name_plural = '职务信息'
        managed = False

    gh = models.CharField("工号", max_length=32, unique=True)
    dwh = models.CharField("单位", max_length=5, choices=Code.DEPARTMENT_CHOICE, blank=True, null=True)
    ksh = models.CharField("科室", max_length=32, blank=True, null=True)
    zwlx = models.CharField("职务类型", max_length=32, choices=Code.ZWLX_CHOICE, blank=True, null=True)
    zw = models.CharField("职务", max_length=32, blank=True, null=True)
    js = models.CharField('角色', max_length=32, choices=Code.JS_CHOICE, blank=True, null=True)


class LogRecord(models.Model):
    text = models.TextField('日志')
    create_time = models.DateTimeField('创建时间', auto_now_add=True)


class WhiteList(models.Model):
    username = models.CharField('学工号', max_length=128)
    reason = models.CharField('意见', max_length=255, blank=True, null=True)
    remarks = models.CharField("备注", max_length=255, blank=True, null=True)
    create_time = models.DateTimeField("创建时间", auto_now_add=True)
    update_time = models.DateTimeField("更新时间", auto_now=True)

    class Meta:
        managed = False
        verbose_name = '疫情防控门禁白名单'
        verbose_name_plural = '疫情防控门禁白名单'


class EntranceGuardList(models.Model):

    class Meta:
        managed = False
        db_table = 'entrance_guard_list'
        verbose_name = '疫情防控门禁ABC监测名单'
        verbose_name_plural = '疫情防控门禁ABC监测名单'

    id = models.AutoField('编号', primary_key=True)
    username = models.CharField(verbose_name="学工号", max_length=64, unique=True)
    nickname = models.CharField(verbose_name="姓名", max_length=64)
    STATUS_CHOICE = (
        (1, '准入'),
        (2, '不准入')
    )
    LEVEL_CHOICE = (
        ('A', 'A类（自由出入）'),
        ('B', 'B类（三天一出）'),
        ('C', 'C类（一进一出）'),
        ('D', 'D类（两进两出）'),
        ('E', 'E类（一天一进）'),
        ('F', 'F类（一天一出）'),
    )
    level = models.CharField('权限级别', choices=LEVEL_CHOICE, max_length=1)
    status = models.IntegerField("状态", choices=STATUS_CHOICE, default=2)
    reason = models.CharField("原因", max_length=255)
    SOURCE_CHOICE = (
        ('线上A类名单', '线上A类名单'),
        ('线上B类名单', '线上B类名单'),
        ('线上C类名单', '线上C类名单'),
        ('线上D类名单', '线上D类名单'),
        ('线上E类名单', '线上E类名单'),
        ('线上F类名单', '线上F类名单'),
        ('线下A类名单', '线下A类名单'),
        ('线下B类名单', '线下B类名单'),
        ('线下C类名单', '线下C类名单'),
        ('线下D类名单', '线下D类名单'),
        ('线下E类名单', '线下E类名单'),
        ('线下F类名单', '线下F类名单'),
        ('校领导名单', '校领导名单'),
    )
    source = models.CharField("数据来源", choices=SOURCE_CHOICE, max_length=255)
    lock = models.BooleanField("是否锁定", help_text='数据来源选择非线上名单时，会自动锁定')
    remarks = models.CharField("备注", max_length=255, null=True, blank=True)
    create_time = models.DateTimeField("创建时间", auto_now_add=True)
    update_time = models.DateTimeField("更新时间", auto_now=True)

    def try_remove(self, report):
        # 是否身体不适
        if not report.is_healthy:
            self.status = 2
            self.reason = '身体不适'
        # 是否离开期间或近30条记录是否到过风险地区
        elif not report.have_never_been_to_risk_area:
            self.status = 2
            self.reason = '前往国内中高风险地区'
        #是否进入指定的重点地区城市
        elif report.have_gone_to_risk_area:
            self.status = 2
            self.reason = '前往国内重点地区城市'
        # 是否在国外
        elif report.current_country not in [142, 710000, 810000, 820000]:
            self.status = 2
            self.reason = '前往境外'
        # 连续打卡大于三天
        elif report.continuous_unreport_days >= 3:
            self.status = 2
            self.reason = '连续三天不打卡'
        self.save()

    def try_add(self, report):
        today = datetime.datetime.today().strftime("%Y-%m-%d")
        if report.is_healthy and report.have_never_been_to_risk_area and report.submit_time == today \
                and report.current_city in (441900,):
            if report.stay_in_guangdong_period_of_leave:
                if not report.with_public_transport:
                    self.status = 1
                    self.reason = '离莞赴省内其他非中高风险地区后，通过自助包车或自驾返莞，身体状况良好'
                elif report.pass_covid_2019_test:
                    self.status = 1
                    self.reason = '离莞赴省内其他非中高风险地区后，通过公共交通返莞，已完成核酸检测'
                elif report.n_days_in_sui_shen_guan_hui >= 14:
                    self.status = 1
                    self.reason = '离莞赴省内其他非中高风险地区后，通过公共交通返莞，已满14天'
            elif report.pass_covid_2019_test:
                self.status = 1
                self.reason = '离莞赴省外非防控中高风险地区后返莞，已完成核酸检测'
            elif report.n_days_in_sui_shen_guan_hui >= 14:
                self.status = 1
                self.reason = '离莞赴省外非防控中高风险地区后返莞，已满14天'
        self.save()

    def save(self, force_insert=False, force_update=False, using=None, update_fields=None):
        super().save(force_insert, force_update, using, update_fields)
        # 缓存到Redis
        code = AccessCheck.ACCESS if self.status == 1 else AccessCheck.NOT_ALLOWED

        data = {
            'username': self.username,
            'nickname': self.nickname,
            'level': self.level,
            'reason': self.reason,
            'code': code
        }
        if self.lock:
            cache.set('access_check_' + self.username, data, timeout=None)
        else:
            cache.set('access_check_' + self.username, data, 60 * 60 * 24)

    def delete(self, using=None, keep_parents=False):
        cache.delete('access_check_{}'.format(self.username))
        super().delete(using, keep_parents)

    def __str__(self):
        return "{}-{}".format(self.username, self.level)


@receiver(post_delete, sender=EntranceGuardList)
def delete_cache(sender, instance, **kwargs):
    print("删除缓存")
    cache.delete('access_check_{}'.format(instance.username))
